#include "DemoJson11.h"

#include <iostream>
using namespace std;

#include "json11.hpp"
using namespace json11;
// using Json11 = json11::Json;


class Point
{
    friend ostream &operator<<(ostream &os, const Point &point);

public:
    int x, y;
    Point(int x, int y) : x(x), y(y) {}
    // explicit 如果不强明确构造，那么 Json 将可以隐式转换成 Point，这可能造成我们不期望的转换错误。
    // 例如：上面重写了输出运算符 operator<< 当我们试图 cout << Json 的时候，在编译器看来事成立的，Json 会被隐式转换为 Point 哪怕这个 Json 解析对象并不是Point。
    explicit Point(Json json) : Point(json["x"].int_value(), json["y"].int_value()) {}
    Json to_json() const
    {
        // return Json::array { x, y };
        return Json::object{{"x", x}, {"y", y}};
    }
};

ostream &operator<<(ostream &os, const Point &point)
{
    os << "Point(" << point.x << "," << point.y << ")";
    return os;
}

void runDemoOfJson11()
{
    // 官方测试Demo：https://github.com/dropbox/json11/blob/master/test.cpp

    // 其他资料：https://blog.csdn.net/zhangzl4321/article/details/129530673
    // const Json obj = Json::object({
    //     { "k1", "v1" },
    //     { "k2", 42.0 },
    //     { "k3", Json::array({ "a", 123.0, true, false, nullptr }) },
    // });

    cout << "======================演示案例======================" << endl;

    Json::object obj1 = {
        {"name", "liuwen"}};
    Json jsonObj1 = obj1;

    Json jsonObj2 = Json::object({{"name", "xiazhihui"}});

    Json jsonObj3 = Json::object{
        {"name", "summer"}};

    std::string objJson1 = jsonObj1.dump();
    std::string objJson2 = jsonObj2.dump();
    std::string objJson3 = jsonObj3.dump();
    cout << "objJson1 = " << objJson1 << endl;
    cout << "objJson2 = " << objJson2 << endl;
    cout << "objJson3 = " << objJson3 << endl;

    cout << "point = " << Json(Point(3, 2)).dump() << endl;

    vector<Point> points = {{10, 20}, {5, 5}, {6, 30}, {100, 100}};
    cout << Json(points).dump() << endl;

    // R"({"x":10,"y":20})" 是一个原始字符串字面量（Raw String Literal）原始字符串字面量允许你包含像引号或换行符这样的特殊字符，而不需要转义它们。
    // 这在处理JSON、正则表达式或其他需要特殊字符的文本时特别有用。
    // 原始字符串字面量以 R" 开始，后面跟着一个括号内的分隔符（在这个例子中是 { 和 }），然后是实际的字符串内容，最后以相同的分隔符和 " 结束。
    // 分隔符可以是任何有效的括号对（例如 (), [], {}, <>），并且它本身不能出现在字符串内容中。
    // 在上面的例子中：() 是分隔符，分隔符包裹的就是真实字符串内容，它等价于普通的字符串字面量 "{\"x\":10,\"y\":20}"
    // string err;
    // Point point(Json::parse(R"({"x":10,"y":20})", err));
    // Point point = Json::parse(R"({"x":10,"y":20})", err);
    // cout << "Point(x,y) = point(" << point.x << "," << point.y << ")"<<endl;
    // cout << point;
    string err;
    cout << "Point(x,y) =" << Point(Json::parse(R"({"x":10,"y":20})", err)) << endl;
}